package com.dongdongshop.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.dongdongshop.config.AlipayConfig;
import com.dongdongshop.constant.PayConstant;
import com.dongdongshop.pojo.*;
import com.dongdongshop.service.AddressService;
import com.dongdongshop.service.OrderService;
import com.dongdongshop.service.PayService;
import com.dongdongshop.service.SeckillService;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 支付回调类
 */
@Controller
@RequestMapping("callback")
public class AliPayCallBackController {

    @Autowired
    private AlipayConfig alipayConfig;

    @Autowired
    private RedisTemplate redisTemplate;
    @Reference(retries = 0,timeout = 10000)
    private OrderService orderService;
    @Reference
    private PayService payService;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    @Reference(timeout = 10000,retries = 0)
    private SeckillService seckillService;

    @Reference
    private AddressService addressService;

    // 同步回调
    /**
     *
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易号
     * @param total_amount 付款金额
     * @param request
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("return")
    public String return_url(String out_trade_no, String trade_no, String total_amount, HttpServletRequest request, Model model) throws Exception {

        model.addAttribute("out_trade_no", out_trade_no);
        model.addAttribute("trade_no", trade_no);
        model.addAttribute("total_amount", total_amount);
        TbUser user = (TbUser) SecurityUtils.getSubject().getPrincipal();
        System.out.println("回调函数");
        if (null != user){
            model.addAttribute("tbUser",user.getUsername());
        }
        return "paysuccess";
    }

    /**
     *
     * @param out_trade_no 商户订单号
     * @param trade_no 支付宝交易号
     * @param trade_status 交易状态
     * @param gmt_create 创建时间
     * @param total_amount 订单金额
     * @param gmt_payment 付款时间
     * @param request
     * @return
     */
    @RequestMapping("notify")
    @ResponseBody
    public String notifyUrl(String out_trade_no, String trade_no, String trade_status, String gmt_create, String total_amount, String gmt_payment,HttpServletRequest request,Model model) throws Exception {

        List<TbOrder> orderList = (List<TbOrder>) orderService.getOrdersByParenOrderId(out_trade_no);
        TbSeckillOrder tbSeckillOrder = seckillService.getSeckillOrderById(out_trade_no);

        if (getSignVerified(request)) {//验证成功

            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (orderList.size() > 0){
                // 创建支付的日志
                TbPayLog tbPayLog = new TbPayLog();
                tbPayLog.setOutTradeNo(out_trade_no);
                tbPayLog.setCreateTime(simpleDateFormat.parse(gmt_create));
                tbPayLog.setUserId(orderList.get(0).getUserId());
                tbPayLog.setTransactionId(trade_no);
                tbPayLog.setOrderList(out_trade_no);
                tbPayLog.setPayType("1");

                if (trade_status.equals("TRADE_CLOSED")) {
//                    // 未付款交易超时关闭，或支付完成后全额退款
//
//                    // 修改支付日志表
//                    tbPayLog.setTotalFee(0L);
//                    tbPayLog.setTradeState("0");
//                    payService.insertPayLog(tbPayLog);
//
//                    // 修改order表中的状态和数据 关闭交易
//                    orderService.updateOrderStatusClose(orderList);
                } else if (trade_status.equals("TRADE_SUCCESS")) {

//                    // 修改order表中的状态和数据
//                    orderService.updateOrderStatus(orderList);

                    // 修改支付日志表
                    Number num = Float.parseFloat(total_amount); // double转lang
                    // tbPayLog.setTotalFee(Long.valueOf(total_amount.substring(0, total_amount.length() - 3))); // 付款金额
                    tbPayLog.setTotalFee(Long.valueOf(num.intValue())); // 付款金额  double转lang
                    tbPayLog.setTradeState("1");
                    tbPayLog.setPayTime(simpleDateFormat.parse(gmt_payment));
                    payService.insertPayLog(tbPayLog);

                    // 增加该用户的积分表中的积分
                    String body = out_trade_no+","+total_amount;
                    Message message = MessageBuilder.withPayload(body).build();
                    //事务消息发送者所在的组    事务消息发送的topic   要发送的消息
                    rocketMQTemplate.sendMessageInTransaction("tx-integral", "IntegralTopic", message, orderList);

                    // 删除redis中的母订单
                    redisTemplate.boundHashOps(PayConstant.PAY_KEY + orderList.get(0).getUserId()).delete(out_trade_no);
                    //注意：
                    //付款完成后，支付宝系统发送该交易状态通知
                }

                return "success";
            }else if (null != tbSeckillOrder){
                if (trade_status.equals("TRADE_SUCCESS")){
                    tbSeckillOrder.setStatus("1"); // 状态 已付款
                    tbSeckillOrder.setPayTime(simpleDateFormat.parse(gmt_payment)); // 付款时间
                    tbSeckillOrder.setTransactionId(trade_no); // 交易号
                    int i = seckillService.updateSeckillOrderStatus(tbSeckillOrder);

                }
                return "success";
            }
            return "fail";
        } else {//验证失败
            return "fail";
            //调试用，写文本函数记录程序运行情况是否正常
            //String sWord = AlipaySignature.getSignCheckContentV1(params);
            //AlipayConfig.logResult(sWord);
        }
    }

    @RequestMapping("toAddress")
    public String toAddress(String out_trade_no,Model model){
        TbSeckillOrder tbSeckillOrder = new TbSeckillOrder();
        tbSeckillOrder.setId(Long.parseLong(out_trade_no));
        model.addAttribute("no",tbSeckillOrder.getId().toString());
        return "getSecAddress";
    }

    // 验证数字签名
    private boolean getSignVerified(HttpServletRequest request) throws Exception {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//             valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(), alipayConfig.getCharset(), alipayConfig.getSign_type()); //调用SDK验证签名
        return signVerified;
    }
}
